﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utiles.Persistencia;

namespace EntidadesDeNegocio
{
    public class Diseno:ObjetoPersistente
    {
        /// <summary>
        /// Lista de componentes del disño
        /// </summary>
        public List<Componente> ListaComponentes { get; set; }
        /// <summary>
        /// Nombre que identifica el diseño
        /// </summary>
        public string Nombre { get; set; }

        /// <summary>
        /// Descripcion del diseño
        /// </summary>
        public string Descripcion { get; set; }

        /// <summary>
        /// El costo es la suma del costo de sus componentes + valor ingresado
        /// </summary>
        public decimal Costo 
            {
                get {
                    decimal retorno = CostoAgregado;
                    if (ListaComponentes.Count != 0)
                    {
                        foreach (Componente comp in ListaComponentes)
                        {
                            retorno = (comp.Costo*comp.Cantidad) + retorno;
                        }
                    }
                    return retorno;
                }
            }

        /// <summary>
        /// Costo del diseño que ingresa el usuario 
        /// </summary>
        public decimal CostoAgregado { get; set; }

        /// <summary>
        /// Fecha de Service de la pieza con la menor fecha de todo el diseno.
        /// </summary>
        public DateTime FechaService 
        {
            get 
            {
                DateTime menorFecha = new DateTime();

                bool primerCorrida = true;
                foreach (Componente comp in ListaComponentes)                
                {
                    if (primerCorrida)
                    {
                        menorFecha = comp.FechaService;
                        primerCorrida = false;
                    }
                    if (comp.FechaService < menorFecha)
                    {
                        menorFecha = comp.FechaService;
                    }
                }
                return menorFecha;
            }
        }


        /// <summary>
        /// Si el existe un componente en el Diseno que necesita que se le realice un service a la fecha de hoy.
        /// </summary>
        /// <returns></returns>
        public bool NecesitaService()
        {
            return this.FechaService < DateTime.Now;
        }  

        /// <summary>
        /// Medio del diseño
        /// </summary>
        public MedioComponente Medio { get; set; }

        /// <summary>
        /// Agrega componente al diseño del mismo tipo que el diseno
        /// </summary>
        /// <param name="componente"></param>
        public void AgregarComponente(Componente componente)
        {
            if (ExisteComponente(componente))
            {
                Componente comp = this.ObtenerComponenteDelDiseno(componente.Modelo);
                comp.Cantidad = comp.Cantidad + 1;
            }
            else
            {
                Componente nuevo = componente.Clone();
                nuevo.Cantidad = 1;            
                ListaComponentes.Add(nuevo);
            }
        }

        public bool ExisteComponente(Componente comp)
        {
            foreach (Componente c in ListaComponentes)
            {
                if (c.Equals(comp))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// Eliminar componente al diseño
        /// </summary>
        /// <param name="componente"></param>
        public void EliminarComponente(Componente componente)
        {
            ListaComponentes.Remove(componente);
        }

        /// <summary>
        /// Elimina un componente del diseño por su modelo
        /// </summary>
        /// <param name="modelo"></param>
        
        public void EliminarComponente(String modelo)
        {
            Componente compABorrar = ObtenerComponente(modelo);
            ListaComponentes.Remove(compABorrar);

        }

        /// <summary>
        /// Obtener el componente de la lista del diseno segun su modelo
        /// </summary>
        /// <param name="modeloComponente"></param>
        /// <returns></returns>
        public Componente ObtenerComponente(String modeloComponente)
        {
            Componente retorno = null;
            foreach (Componente c in ListaComponentes)
            {                
                retorno=c.ObtenerComponente(modeloComponente);
                if (retorno != null)
                {
                    return retorno;
                }
            }            
           return retorno;
        }

        /// <summary>
        /// Retorna un componente del diseno. No busca el componente en sus robots.
        /// </summary>
        /// <param name="modelo"></param>
        /// <returns></returns>
        public Componente ObtenerComponenteDelDiseno(String modelo)
        {
            Componente retorno = null;
            foreach (Componente c in ListaComponentes)
            {
                if (c.Modelo.ToLower() == modelo.ToLower())
                {
                    return c;
                }               
            }
            return retorno;
        }
     
        /// <summary>
        /// Constructor con parametros
        /// </summary>
        public Diseno(String nombre, MedioComponente medio, decimal CostoAgregado) 
        {
            ListaComponentes = new List<Componente>();
            this.Nombre = nombre;
            this.Medio = medio;
            this.CostoAgregado = CostoAgregado;
        }
        /// <summary>
        /// Constructor por defecto
        /// </summary>
        public Diseno()
        {
            ListaComponentes = new List<Componente>();
        }

        /// <summary>
        /// Los disenos se comparan por su nombre.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override bool Equals(object obj)
        {            
            bool valor ;
            try 
            {
                valor = this.Nombre == ((Diseno)obj).Nombre;
                return valor;
            }
            catch 
            {
                return base.Equals(obj);
            }            
        }
        /// <summary>
        /// Se redefine hashcode
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        /// <summary>
        /// Los disenos se muestran con su nombre
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return this.Nombre;
        }

    }
}
